package xin.nick.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import xin.nick.common.util.MyAssert;
import xin.nick.domain.dto.UserSetRoleListDTO;
import xin.nick.domain.vo.UserSetRoleListVO;
import xin.nick.entity.Role;
import xin.nick.entity.SystemUser;
import xin.nick.entity.UserRole;
import xin.nick.manager.RoleManager;
import xin.nick.mapper.RoleMapper;
import xin.nick.mapper.SystemUserMapper;
import xin.nick.mapper.UserRoleMapper;
import xin.nick.service.IUserRoleService;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户角色关联 服务实现类
 * </p>
 *
 * @author Nick
 * @since 2022-08-10
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRole> implements IUserRoleService {

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private RoleManager roleManager;

    @Autowired
    private SystemUserMapper systemUserMapper;

    @Override
    public List<Role> getRoleListByUserId(Long userId) {

        List<Role> roleList = new ArrayList<>();

        checkUser(userId);

        // 首先从用户-角色关联中拿到角色id列表,
        List<UserRole> userRoleList = list(Wrappers.<UserRole>lambdaQuery().eq(UserRole::getUserId, userId));
        if (CollectionUtils.isEmpty(userRoleList)) {
            return roleList;
        }
        List<Long> roleIdList = userRoleList.parallelStream()
                .filter(Objects::nonNull)
                .map(UserRole::getRoleId)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(roleIdList)) {
            return roleList;
        }

        // 之后获取角色列表
        roleList = roleMapper.selectBatchIds(roleIdList);

        return roleList;
    }

    /**
     * 设置用户角色列表
     * @param userSetRoleListDTO
     * @return
     */
    @Override
    public UserSetRoleListVO setUserRoleList(UserSetRoleListDTO userSetRoleListDTO) {

        List<Long> roleIdList = userSetRoleListDTO.getRoleIdList();
        Long userId = userSetRoleListDTO.getUserId();
        checkUser(userId);

        UserSetRoleListVO userSetRoleListVO = buildUserSetRoleListVO(userSetRoleListDTO);

        // 删除以前记录
        remove(Wrappers.<UserRole>lambdaQuery().eq(UserRole::getUserId, userId));

        // 过滤不存在的角色
        roleIdList = roleManager.filterExistingIdList(roleIdList);

        // 补充新记录
        if (CollectionUtils.isEmpty(roleIdList)) {
            return userSetRoleListVO;
        }

        List<UserRole> insertUserRoleList = new ArrayList<>();
        for (Long roleId : roleIdList) {
            UserRole userRole = new UserRole();

            userRole.setUserId(userId);
            userRole.setRoleId(roleId);
            insertUserRoleList.add(userRole);

        }
        saveBatch(insertUserRoleList);

        return userSetRoleListVO;
    }

    /**
     * 检查用户信息 是否存在
     * @param userId
     */
    public void checkUser(Long userId) {
        MyAssert.notNull(userId, "[userId] 不可为空");
        SystemUser systemUser = systemUserMapper.selectById(userId);
        MyAssert.notNull(systemUser, "用户信息不存在");
    }

    /**
     * 组装 设置用户角色列表的 返回信息
     * @param userSetRoleListDTO
     * @return
     */
    private UserSetRoleListVO buildUserSetRoleListVO(UserSetRoleListDTO userSetRoleListDTO) {

        UserSetRoleListVO result = new UserSetRoleListVO();

        Long userId = userSetRoleListDTO.getUserId();
        List<Long> roleIdList = userSetRoleListDTO.getRoleIdList();


        return result;
    }

}
